/**
 * 文件名称:  DateUtils.java
 * 文件序号:  序号
 * 内容描述:  文件简单描述，多行换行书写
 * 版权声明:  山东鸿蝶信息技术有限公司
 * 创建用户:  zhangkai
 * 创建日期:  2017/1/16 11:44
 * 修改用户:  无
 * 修改日期:  无
 * 修改说明:  无
 * 文件版本:  V1.0
 * 文件路径:
 */

package com.hongdee.common.util;


import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.LongSummaryStatistics;


/**
 * 名  称:DateUtils
 * 类  型: class
 * 描  述: 用一句话描述类的作用
 * 路  径:com.hongdee.common.util
 * 作  者:zhangkai
 * 日  期:2017/1/16 11:44
 */
public final class DateUtils {
    /**
     *
     */
    private DateUtils() {

    }

    public static String YYYYMMDD="yyyy-MM-dd";

    /**
     * @return String 格式化后的字符串
     * @throws
     * @desc 返回日期格式 2016-10-22 17:00:99
     * @author zhangkai
     * @date 2017/2/8
     * @time 17:52
     * @update_user
     * @update_time
     * @update_desc:
     */
    public static String getTimeStr() {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return sf.format(new Date());
    }

    public static String getTimeStr24() {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sf.format(new Date());
    }

    public static String getTimeStr(String format) {
        SimpleDateFormat sf = new SimpleDateFormat(format);
        return sf.format(new Date());
    }

    public static String getTimeStr(String time,String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINESE);
        return sdf.format(sdf.parse(time));
    }

    public static String getTimeStr(Date date, String format) {
        SimpleDateFormat sf = new SimpleDateFormat(format);
        return sf.format(date);
    }

    /***
     * TimeZone 时间字符串转时间
     * @param str
     * @return
     * @throws Exception
     */
    public static Long parseTimeZoneStr(String str) throws Exception {
        //str = "2017-02-24T02:46:43.594Z";
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.CHINESE);
        return sdf.parse(str).getTime();
    }

    public static Long parseTimeZoneStrToDay(String str) throws Exception {
        //str = "2017-02-24T02:46:43.594Z";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.CHINESE);
        Date d = new Date(sdf.parse(str).getTime());
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE);
        return sdf2.parse(sdf2.format(d)).getTime();
    }

    public static Long parseTimeStr(String str) throws Exception {
        //str = "2017-02-24 02:46:43";
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINESE);
        return sdf.parse(str).getTime();
    }

    public static String formatLongTime(Long time) throws Exception {
        //str = "2017-02-24T02:46:43.594Z";
        Date d = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(d);
    }
    public static String formatLongTimeByYYYYMMDD(Long time) throws Exception {
        //str = "2017-02-24T02:46:43.594Z";
        Date d = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(d);
    }

    public static String formatLongTime(Long time, String format) throws Exception {
        //str = "2017-02-24T02:46:43.594Z";
        Date d = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(d);
    }

    /**
     * 字符串日期（YYYY-MM-DD HH:mm:ss）转为时间戳
     * @return
     * @throws Exception
     */
    public static Long DateStrToLong(String str) throws Exception{
        SimpleDateFormat stf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
        return stf.parse(str).getTime();
    }

    /**
     * 计算向前 或向后 几个月的时间戳
     *
     * @param time
     * @return
     * @throws Exception
     */
    public static Long addMonthLongTime(Long time, int month) throws Exception {
        //日历对象
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime().getTime();
    }

    /**
     * 计算指定日期向前或向后几天的时间戳
     *
     * @param time
     * @param day
     * @return
     * @throws Exception
     */
    public static Long addDayLongTime(Long time, int day) throws Exception {
        //日历对象
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime().getTime();
    }

    public static Long addHourLongTime(Long time,int hour){

        //日历对象
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime().getTime();
    }

    /**
     * 日期转毫秒数
     *
     * @param day
     * @return
     * @throws Exception
     */
    public static Long dayToLongTime(String day) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.parse(day).getTime();
    }

    /**
     * 日期转毫秒数
     *
     * @param day
     * @return
     * @throws Exception
     */
    public static Long dayToLongTimes(String day) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        return sdf.parse(day).getTime();
    }

    /**
     * 获取月初时间
     *
     * @param months
     * @return
     * @throws Exception
     */
    public static Long monthSToLongTime(String months) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        return sdf.parse(months).getTime();
    }

    /**
     * 获得月初时间
     * @param months
     * @return
     * @throws Exception
     */
    public static String monthSToStrTime(String months)throws Exception{
        Long timeL=monthSToLongTime(months);
        return formatLongTime(timeL);
    }

    /**
     * 获得当月初时间
     * @return
     * @throws Exception
     */
    public static String monthSToStrTime() throws Exception {
        Calendar cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 0);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        return formatLongTimeByYYYYMMDD(cale.getTime().getTime());
    }

    public static String monthMToStrTime() throws Exception {
        Calendar cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        return formatLongTimeByYYYYMMDD(cale.getTime().getTime());
    }


    /**
     * 获取年初时间
     *
     * @param months
     * @return
     * @throws Exception
     */
    public static Long yearSToLongTime(String months) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        return sdf.parse(months).getTime();
    }

    /**
     * 计算两个日期之间的差，返回中间差的天数
     *
     * @param afterTime
     * @param beforeTime
     * @return
     */
//    public static float dateDifference(Long afterTime, Long beforeTime) {
//        return (afterTime - beforeTime) / (24 * 60 * 60 * 1000);
//    }


    public static Integer dateDifference(Long afterTime, Long beforeTime) throws ParseException {
        Date smdate=new Date(afterTime);
        Date bdate=new Date(beforeTime);
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));

        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();

        long between_days=(time2-time1)/(1000*3600*24);

        Integer days=Integer.parseInt(String.valueOf(between_days));
        BigInteger b=new BigInteger(days.toString());

        return b.abs().intValue();
    }

    /**
     * 检测时间，检测任务时间是否在下月初与下下月初之间,如当前是3月
     *
     * @param taskTime 指定时间
     * @param nowTime  当前时间
     * @return
     * @throws Exception
     */
    public static boolean checkTime(Long taskTime, Long nowTime) throws Exception {
        //4月
        long l1 = addMonthLongTime(nowTime, +1);
        //5月
        long l2 = addMonthLongTime(nowTime, +2);
        String st1 = formatLongTime(l1);
        //转换为 yyyy-4-1 00:00:00
        long nextMonth = monthSToLongTime(st1);
        String st2 = formatLongTime(l2);
        //转换为 yyyy-5-1 00:00:00
        long nextNextMonth = monthSToLongTime(st2);
        //判断任务时间是否在指定日期范围以内
        if (taskTime < nextMonth) {
            return false;
        }
        if (taskTime > nextNextMonth) {
            return false;
        }
        if (taskTime >= nextMonth & taskTime < nextNextMonth) {

            return true;
        }
        return false;
    }

    /**
     * 转换时间

     * **/
    public static long parseTime(String timeStr, String format) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(timeStr).getTime();
    }

    /**
     * 判断某个时间是否在时间段以内
     * @param time
     * @param startTime
     * @param endTime
     * @return
     * @throws Exception
     */
    public static boolean checkTime(long time,String startTime,String endTime) throws Exception {
        if(startTime==null || "".equals(startTime)){
            return true;
        }
        if(endTime==null || "".equals(endTime)){
            return true;
        }
        String timeStr=DateUtils.formatLongTime(time,"yyyy-MM-dd");
        Long timeL=parseTime(timeStr,"yyyy-MM-dd");
        Long startTimeL=parseTime(startTime,"yyyy-MM-dd");
        Long endTimeL=parseTime(endTime,"yyyy-MM-dd");
        if (timeL < startTimeL) {
            return false;
        }
        if (timeL > endTimeL) {
            return false;
        }
        if (timeL >= startTimeL && timeL <= endTimeL) {
            return true;
        }
        return false;
    }

    /**
     * 获得周一的日期
     * @param time
     * @return
     * @throws ParseException
     */
    public static String getMonday(String time) throws ParseException {
        if(time.equals("")){
            time=getTimeStr();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(time));
        int d = 0;
        if(cal.get(Calendar.DAY_OF_WEEK)==1){
            d = -6;
        }else{
            d = 2-cal.get(Calendar.DAY_OF_WEEK);
        }
        cal.add(Calendar.DAY_OF_WEEK, d);
        return new SimpleDateFormat("yyyy-MM-dd 00:00:00").format(cal.getTime());
    }

    /**
     * 获得周末的时间
     * @param time
     * @return
     * @throws ParseException
     */
    public static String getWeekday(String time) throws ParseException {
        if(time.equals("")){
            time=getTimeStr();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(time));
        int d = 0;
        if(cal.get(Calendar.DAY_OF_WEEK)==1){
            d = -6;
        }else{
            d = 2-cal.get(Calendar.DAY_OF_WEEK);
        }
        cal.add(Calendar.DAY_OF_WEEK, d);
        cal.add(Calendar.DAY_OF_WEEK, 6);
        //所在周结束日期
        return new SimpleDateFormat("yyyy-MM-dd 23:59:59").format(cal.getTime());
    }

    public static boolean checkTime(String time, String startTime, String endTime) throws Exception {
        Long timeL = parseTime(time, "yyyy-MM-dd");
        return checkTime(timeL, startTime, endTime);
    }


    public static Long getNowTime() throws Exception {
        String nowTimeStr = DateUtils.getTimeStr("yyyy-MM-dd'T'00:00:00.000'Z'");
        long nowTime = DateUtils.parseTimeZoneStr(nowTimeStr);
        return nowTime;
    }

    public static String towYearAgo() throws Exception {
        //获得当前时间的时间戳
        String nowTimeStr = DateUtils.getTimeStr("yyyy-MM-dd");
        long currentTime = DateUtils.parseTime(nowTimeStr + " 24:00:00", "yyyy-MM-dd HH:mm:ss");
        //一年前
        long oneYearAgo = DateUtils.addMonthLongTime(currentTime, -24);
        String oneYearStr = DateUtils.formatLongTime(oneYearAgo,"yyyy-MM-dd");
        return oneYearStr;
    }

    public static String oneYearAge() throws Exception {
        //获得当前时间的时间戳
        String nowTimeStr = DateUtils.getTimeStr("yyyy-MM-dd");
        long currentTime = DateUtils.parseTime(nowTimeStr + " 24:00:00", "yyyy-MM-dd HH:mm:ss");
        //两年前
        long twoYearAgo = DateUtils.addMonthLongTime(currentTime, -12);
        String twoYearAgoStr = DateUtils.formatLongTime(twoYearAgo, "yyyy-MM-dd");
        return twoYearAgoStr;
    }

    public static String getMonthFirstDay(String date,String format) throws Exception{
        Calendar cal = Calendar.getInstance();
        cal.setTime(new SimpleDateFormat(format).parse(date));
        cal.add(Calendar.MONTH,0);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        System.out.println(new SimpleDateFormat(format).format(cal.getTime()));
        return new SimpleDateFormat(format).format(cal.getTime());
    }

    public static String getMonthLastDay(String date,String format) throws Exception{
        Calendar cal = Calendar.getInstance();
        cal.setTime(new SimpleDateFormat(format).parse(date));
        cal.add(Calendar.MONTH,0);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        System.out.println(new SimpleDateFormat(format).format(cal.getTime()));
        return new SimpleDateFormat(format).format(cal.getTime());

    }

    public static String getPreMonthFirstDay(String format) throws Exception{
        Calendar cal = Calendar.getInstance();

        cal.add(Calendar.MONTH,0);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        System.out.println(new SimpleDateFormat(format).format(cal.getTime()));
        return new SimpleDateFormat(format).format(cal.getTime());
    }

    public static String getPreMonthLastDay(String format) throws Exception{
        Calendar cal = Calendar.getInstance();

        cal.add(Calendar.MONTH,0);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        System.out.println(new SimpleDateFormat(format).format(cal.getTime()));
        return new SimpleDateFormat(format).format(cal.getTime());

    }
    public static void main(String[] args) throws Exception {
        System.out.println(monthSToStrTime());
        System.out.println(monthMToStrTime());;

    }

}
